﻿/*
 * Created by SharpDevelop.
 * User: kwu
 * Date: 2007-4-15
 * Time: 15:07
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections;
using System.Text;

//TODO: 是不是应该把游戏规则和命令处理分开？
namespace msnkiller
{
	/// <summary>
	/// Description of Judge.
	/// </summary>
	public class Judge
	{
	  const string welcomeMsg = "您好，欢迎加入对话，输入/left离开对话";
    const string goodbyeMsg = "再见";  
    const string gameStartMsg = "游戏开始";
    const string gameOverMsg = "游戏结束";
    
	  private ArrayList fPlayers = new ArrayList();
	  private ArrayList fCommands = new ArrayList();
	  
	  public delegate void SaybackDelegate(string msg, ArrayList players);
	  private SaybackDelegate fSaidBack = null;
	  //TODO: 考虑改为event
    public SaybackDelegate SaidBack {
      get { return fSaidBack; }
      set { fSaidBack = value; }
    }
	  
		public Judge()
		{
		  fCommands.Add(new Command("/e", ShowEchoCmd));
		  fCommands.Add(new Command("/p", ShowPlayersCmd));
		  fCommands.Add(new Command("/left", PlayerLeftCmd));
		  fCommands.Add(new Command("", BroadcastCmd));
		}
		
		private string BroadcastCmd(Player player, ArrayList sendToAccounts, string msg)
		{
	    foreach(Player item in fPlayers)
	    {
	      sendToAccounts.Add(item.Mail);
	    }
	    if (!player.ShowEcho)
	    {
	      sendToAccounts.Remove(player.Mail);
	    }
	    return player.Mail + ": " + msg;
		}
		
		private string ShowEchoCmd(Player player, ArrayList sendToAccounts, string msg)
		{
		  player.ShowEcho = !player.ShowEcho;
		  sendToAccounts.Add(player.Mail);
		  return "发送回声：" + GetSwitchText(player.ShowEcho);
		}
		
		private string ShowPlayersCmd(Player player, ArrayList sendToAccounts, string msg)
		{
		  sendToAccounts.Add(player.Mail);
		  return GetPlayerListText();
		}
		  
		private string PlayerLeftCmd(Player player, ArrayList sendToAccounts, string msg)
		{
		  RemovePlayer(player);
		  sendToAccounts.Add(player.Mail);
		  return goodbyeMsg;
		}
		
		private string GetPlayerListText()
		{
		  //TODO: 改用format
		  StringBuilder text = new StringBuilder();
		  text.Append("当前对话中有").Append(fPlayers.Count).AppendLine("个人：");
		  
		  for(int i=0; i<fPlayers.Count; i++)
		  {
		    Player p = fPlayers[i] as Player;
		    text.Append(i+1).Append(", ").AppendLine(p.Mail);
		  }
		  return text.ToString();
		}
		
		public void SbSay(string mail, string msg)
		{
		  ArrayList accounts = new ArrayList();;
		  //TODO: 加入对话也用command实现
		  Player player = GetPlayer(mail);
		  if (player == null)
		  {
   		  player = RegPlayer(mail);
   		  accounts.Add(mail);
   		  DoPlayerSaying(welcomeMsg, accounts);
		  }
		  else 
		  {
		    string returnMsg = "";
		    foreach (Command cmd in fCommands)
		    {
		      if (msg == cmd.Pattern || cmd.Pattern == "")
		      {
		        returnMsg = cmd.Execute(player, accounts, msg);
      		  DoPlayerSaying(returnMsg, accounts);
		        break;
		      }
		    }
		  }
		}

		private void RemovePlayer(Player player)
		{
		  fPlayers.Remove(player);
		}
		
		private string GetSwitchText(bool open)
		{
		  if (open)
		  {
		    return "开";
		  }
		  else
		  {
		    return "关";
		  }
		}
		  
		private Player GetPlayer(string mail)
		{
		  foreach (Player item in fPlayers)
		  {
		    if (item.Mail == mail)
		    {
		      return item;
		    }
		  }
		  return null;
		}
			
		private void DoPlayerSaying(string msg, ArrayList players)
		{
		  if (fSaidBack != null)
		  {
		    fSaidBack(msg, players);
		  }
		}
		
		private Player RegPlayer(string mail)
		{
		  Player player = GetPlayer(mail);
		  if (player == null)
		  {
  		  player = new Player(mail);
  		  fPlayers.Add(player);
		  }
 		  return player;
		}
		
		public void StartGame()
		{
		  ArrayList accounts = new ArrayList();
	    foreach(Player item in fPlayers)
	    {
	      accounts.Add(item.Mail);
	    }
		  DoPlayerSaying(gameStartMsg, accounts);
		}
		
		public void ChangeState()
		{
		  ArrayList accounts = new ArrayList();
	    foreach(Player item in fPlayers)
	    {
	      accounts.Add(item.Mail);
	    }
	    DoPlayerSaying(gameOverMsg, accounts);
		}
	}
}
